import { keywords } from "./keywords";
export type IMonacoVersion = "0.13.2" | "0.15.6";
import genericAutocompleteParser from "../generic/genericAutocompleteParser";
import { AutocompleteParseResult } from "../generic/sql/types";
import parser from "./parserSql";
export default class Snippets {
	public SORT_TEXT = {
		Database: "C",
		Table: "B",
		Column: "A",
		Keyword: "D",
	};

	public dbKeywords: string = [];

	public keywordKind;
	public databaseKind;
	public tableKind;
	public fieldKind;
	public functionKind;

	constructor(
		public monaco: any,
		public customKeywords = [],
		public selectedCatalog,
		public onInputTableColumn,
		public onInputTableAila,
		public dbSchema
	) {
		if (!dbSchema) {
			dbSchema = [
				{
					dbName: "",
					tables: [
						{
							tblName: "",
							tableColumns: [],
						},
					],
				},
			];
		}
		this.selectedCatalog = selectedCatalog;
		this.customKeywords = customKeywords;
		this.dbKeywords = [...keywords, ...customKeywords];
		this.dbSchema = dbSchema;
		this.monaco = monaco;
		this.getKeywordSuggest = this.getKeywordSuggest.bind(this);
		this.getTableSuggest = this.getTableSuggest.bind(this);
		// 字段联想callback
		this.onInputTableColumn = onInputTableColumn;
		// <别名>.<字段>联想callback
		this.onInputTableAila = onInputTableAila;
		this.keywordKind = this.monaco.languages.CompletionItemKind.Keyword;
		this.databaseKind = this.monaco.languages.CompletionItemKind.Class;
		this.tableKind = this.monaco.languages.CompletionItemKind.Struct;
		this.fieldKind = this.monaco.languages.CompletionItemKind.Field;
		this.functionKind = this.monaco.languages.CompletionItemKind.Function;
	}

	public monacoEditorVersion: IMonacoVersion = "0.15.6";

	/**
	 * 动态设置数据库表&&数据库字段
	 * @param {*} dbSchema 数据库schema
	 * @example [{ dbName: '', tables: [{ tblName: '', tableColumns: [] }] }]
	 */
	setDbSchema(dbSchema) {
		this.dbSchema = dbSchema;
	}

	setSelectedCatalog(selectedCatalog) {
		this.selectedCatalog = selectedCatalog;
	}

	getGenericAutocompleteParser(sqls) {
		return genericAutocompleteParser.parseSql(sqls, "");
	}

	/**
	 * monaco提示方法
	 * @param {*} model
	 * @param {*} position
	 */
	async provideCompletionItems(model, position) {
		const { lineNumber, column } = position;
		// 光标前文本
		const textBeforePointer = model.getValueInRange({
			startLineNumber: lineNumber,
			startColumn: 0,
			endLineNumber: lineNumber,
			endColumn: column,
		});
		const textBeforePointerMulti = model.getValueInRange({
			startLineNumber: 1,
			startColumn: 0,
			endLineNumber: lineNumber,
			endColumn: column,
		});
		// 光标后文本
		// const textAfterPointer = model.getValueInRange({
		//   startLineNumber: lineNumber,
		//   startColumn: column,
		//   endLineNumber: lineNumber,
		//   endColumn: model.getLineMaxColumn(model.getLineCount())
		// })
		const textAfterPointerMulti = model.getValueInRange({
			startLineNumber: lineNumber,
			startColumn: column,
			endLineNumber: model.getLineCount(),
			endColumn: model.getLineMaxColumn(model.getLineCount()),
		});
		let result = genericAutocompleteParser.parseSql(
			textBeforePointerMulti,
			textAfterPointerMulti
		);
		let suggestions = [];
		await this.update(
			result,
			suggestions,
			textBeforePointerMulti,
			textAfterPointerMulti
		);
		await this.defaultUpdate(
			suggestions,
			textBeforePointerMulti,
			textAfterPointerMulti
		);
		return returnCompletionItemsByVersion(
			suggestions,
			this.monacoEditorVersion
		);
	}

	async defaultUpdate(
		suggestions: [],
		textBeforePointerMulti,
		textAfterPointerMulti
	) {
		if (suggestions.length == 0) {
			let sqls = parser(textBeforePointerMulti.trim());
			const beforeTokens = sqls[sqls.length - 1].reverse();
			sqls = parser(textAfterPointerMulti.trim());
			const afterTokens = sqls[0];
			const lastToken =
				beforeTokens[0].toLowerCase();
			// 去掉点后的字符串
			let tokenNoDot = lastToken.slice(0, lastToken.length - 1).trim();
			let tableSources = this.parserTableSource(tokenNoDot);
			if (lastToken.endsWith(".")) {
				await this.tableResourceHandle(suggestions, tableSources);
				if (tableSources.length === 1) {
					if (
						!this.dbSchema.some(
							(key) =>
								key.dbName.toUpperCase() ===
								tableSources[0].toUpperCase()
						) ||
						!this.selectedCatalog ||
						!this.dbSchema.some(
							(db) =>
								db.dbName.toUpperCase() ===
									this.selectedCatalog.toUpperCase() &&
								db.tables.some(
									(tb) =>
										tb.tblName.toUpperCase() ===
										tableSources[0].toUpperCase()
								)
						)
					) {
						let beforeTokenIndex = beforeTokens.findIndex(
							(token, index) =>
								index < (beforeTokens.length-1) &&
								token == tableSources[0] &&
								beforeTokens[index + 1] != "," &&
								!this.dbKeywords.some(
									(key) =>
										key.toUpperCase ===
										beforeTokens[index + 1].toUpperCase()
								)
						);
						let afterTokenIndex = afterTokens.findIndex(
							(token, index) =>
								index > 0 &&
								token == tableSources[0] &&
								afterTokens[index - 1] != "," &&
								!this.dbKeywords.some(
									(key) =>
										key.toUpperCase ===
										afterTokens[index - 1].toUpperCase()
								)
						);
						if (beforeTokenIndex > 0) {
							await this.tableResourceHandle(
								suggestions,
								this.parserTableSource(
									beforeTokens[
										beforeTokenIndex + 1
									].toUpperCase() === "AS"
										? beforeTokens[beforeTokenIndex + 2]
										: beforeTokens[beforeTokenIndex + 1]
								)
							);
						}
						if (beforeTokenIndex<=0&&afterTokenIndex > 0) {
							await this.tableResourceHandle(
								suggestions,
								this.parserTableSource(
									afterTokens[
										afterTokenIndex - 1
									].toUpperCase() === "AS"
										? afterTokens[afterTokenIndex - 2]
										: afterTokens[afterTokenIndex - 1]
								)
							);
						}
						if (suggestions.length === 0) {
							beforeTokenIndex = beforeTokens.findIndex(
								(token, index) =>
									index < (beforeTokens.length-1)  && token == tableSources[0]
							);
							afterTokenIndex = afterTokens.findIndex(
								(token, index) =>
									index > 0 && token == tableSources[0]
							);
							if (
								beforeTokenIndex > 0 &&
								this.selectedCatalog &&
								this.dbSchema.some(
									(db) =>
										db.dbName.toUpperCase() ===
											this.selectedCatalog.toUpperCase() &&
										db.tables.some(
											(tb) =>
												tb.tblName.toUpperCase() ===
												tableSources[0].toUpperCase()
										)
								)
							) {
								await this.tableResourceHandle(
									suggestions,
									this.parserTableSource(
										beforeTokens[beforeTokenIndex]
									)
								);
							}
							if (
								beforeTokenIndex <= 0 &&
								afterTokenIndex > 0 &&
								this.selectedCatalog &&
								this.dbSchema.some(
									(db) =>
										db.dbName.toUpperCase() ===
											this.selectedCatalog.toUpperCase() &&
										db.tables.some(
											(tb) =>
												tb.tblName.toUpperCase() ===
												tableSources[0].toUpperCase()
										)
								)
							) {
								await this.tableResourceHandle(
									suggestions,
									this.parserTableSource(
										afterTokens[afterTokenIndex]
									)
								);
							}
						}
						if (suggestions.length === 0) {
							beforeTokenIndex = beforeTokens.findIndex(
								(token, index) =>
									index < beforeTokens.length - 1 &&
									token.endsWith("." + tableSources[0])
							);
							afterTokenIndex = afterTokens.findIndex(
								(token, index) =>
									index > 0 &&
									token.endsWith("." + tableSources[0])
							);
							if (beforeTokenIndex > 0) {
								await this.tableResourceHandle(
									suggestions,
									this.parserTableSource(
										beforeTokens[beforeTokenIndex]
									)
								);
							}
							if (beforeTokenIndex <= 0 && afterTokenIndex > 0) {
								await this.tableResourceHandle(
									suggestions,
									this.parserTableSource(
										afterTokens[afterTokenIndex]
									)
								);
							}
						}
					}
				}
			} else if (lastToken.indexOf(".") && tableSources.length > 0) {
				this.tableResourceHandle(suggestions, [tableSources[0]]);
			}
		}

		suggestions.forEach((s) => {
			s.sortText = "A" + s.sortText;
		});
		const unimportance = [];
		//if (textBeforePointerMulti.endsWith(" ")) {
		unimportance.push(...this.getKeywordSuggest());
		unimportance.push(...this.getDataBaseSuggest());
		if (this.selectedCatalog) {
			unimportance.push(
				...this.getTableSuggestByDbName(this.selectedCatalog)
			);
		}
		unimportance.forEach((s) => {
			s.sortText = "B" + s.sortText;
		});
		for (let u of unimportance) {
			if (
				!suggestions.some(
					(s) =>
						s.label.toUpperCase() === u.label.toUpperCase() &&
						s.kind === u.kind
				)
			) {
				suggestions.push(u);
			}
		}
		//}
	}

	async tableResourceHandle(suggestions, tableSources) {
		if (tableSources.length === 1) {
			suggestions.push(...this.getTableSuggestByDbName(tableSources[0]));
			if (this.selectedCatalog) {
				const reslt = await this.getTableColumn(
					this.selectedCatalog,
					tableSources[0]
				);
				suggestions.push(...reslt);
			}
		}
		if (
			tableSources.length === 2 &&
			this.dbSchema.some(
				(key) =>
					key.dbName.toUpperCase() === tableSources[0].toUpperCase()
			) &&
			this.dbSchema.some(
				(db) =>
					db.dbName.toUpperCase() === tableSources[0].toUpperCase() &&
					db.tables.some(
						(tb) =>
							tb.tblName.toUpperCase() ===
							tableSources[1].toUpperCase()
					)
			)
		) {
			const reslt = await this.getTableColumn(
				tableSources[0],
				tableSources[1]
			);
			suggestions.push(...reslt);
		}
	}

	tokenize(sql) {
		// 移除注释
		sql = sql
			.replace(/--.*?\n|--.*$/gm, "")
			.replace(/\/\*[\s\S]*?\*\//g, "");

		// 定义关键字、运算符、分隔符及正则表达式
		const keywords = [
			"SELECT",
			"FROM",
			"WHERE",
			"AND",
			"OR",
			"IN",
			"BETWEEN",
			"LIKE",
			"IS",
			"NOT",
			"NULL",
			"INNER",
			"LEFT",
			"RIGHT",
			"JOIN",
			"ON",
			"GROUP BY",
			"HAVING",
			"ORDER BY",
			"ASC",
			"DESC",
			"LIMIT",
		];
		const operators = [
			"=",
			"<>",
			"<",
			"<=",
			">",
			">=",
			"+",
			"-",
			"*",
			"/",
			"%",
		];
		const delimiters = ["(", ")", ",", ";"];
		const regex = /[a-zA-Z_][a-zA-Z0-9_]*/;

		let tokens = [];

		// 按照空格分隔SQL语句
		let parts = sql.split(/\s+/);

		// 逐个处理分隔后的部分
		for (let i = 0; i < parts.length; i++) {
			let part = parts[i].toUpperCase();
			let next = parts[i + 1];

			// 判断是否为关键字
			if (keywords.includes(part)) {
				tokens.push({ type: "keyword", value: part });
			}
			// 判断是否为运算符
			else if (operators.includes(part)) {
				tokens.push({ type: "operator", value: part });
			}
			// 判断是否为分隔符
			else if (delimiters.includes(part)) {
				tokens.push({ type: "delimiter", value: part });
			}
			// 判断是否为数字
			else if (/^\d+$/.test(part)) {
				tokens.push({ type: "number", value: parseInt(part) });
			}
			// 判断是否为字符串
			else if (/^'[^']*'$/.test(part)) {
				tokens.push({ type: "string", value: part.slice(1, -1) });
			}
			// 判断是否为标识符
			else if (regex.test(part)) {
				tokens.push({ type: "identifier", value: part });
			}

			// 处理括号后的空格
			if (part === "(" && next === " ") {
				tokens.push({ type: "delimiter", value: "(" });
			} else if (part === ")" && next === " ") {
				tokens.push({ type: "delimiter", value: ")" });
			}
		}

		return tokens;
	}

	public update?: (
		result: AutocompleteParseResult,
		suggestions: [],
		textBeforePointerMulti: String,
		textAfterPointerMulti: String
	) => Promise<any> = (result, suggestions) => {
		const promises: Promise<void>[] = [];
		const trackPromise = (promise: Promise<[]>): Promise<[]> => {
			const wrapped = new Promise<void>((resolve) => {
				promise
					.then((newSuggestions) => {
						if (newSuggestions && newSuggestions.length) {
							suggestions.push(...newSuggestions);
						}
						resolve();
					})
					.catch(resolve);
			});
			promises.push(wrapped);
			return promise;
		};
		trackPromise(this.handleKeywords(result));
		trackPromise(this.handleDatabases(result));
		trackPromise(this.handleTables(result));
		trackPromise(this.handleColumns(result));
		return Promise.all(promises);
	};

	parserTableSource(token: String) {
		token = token.split("").reverse().join("");
		const quoteChar = "`";
		const splitChar = ".";
		let quoteCharFlag = false;
		const stringArray = [];
		let commaChar = [",", ">", "<", "=", "<=", ">=", "<>", "(", ")"];
		let commaState = false;
		let arr = [];
		for (const t of token) {
			if (t === quoteChar) {
				if (quoteCharFlag) {
					quoteCharFlag = false;
				} else {
					quoteCharFlag = true;
				}
				continue;
			}
			if (commaChar.includes(t) && !quoteCharFlag) {
				break;
			}
			arr.push(t);
		}
		if (arr.length > 0) {
			token = arr.reverse().join("");
			arr = [];
		}
		let newtoken = token.trim();

		for (let i of newtoken) {
			if (i === quoteChar) {
				if (quoteCharFlag) {
					quoteCharFlag = false;
				} else {
					quoteCharFlag = true;
				}
				continue;
			}
			if (i === splitChar && !quoteCharFlag) {
				if (arr.length > 0) stringArray.push(arr.join(""));
				arr = [];
				continue;
			}
			arr.push(i);
		}
		if (arr.length > 0) {
			stringArray.push(arr.join(""));
		}
		if (stringArray.length === 0) {
			stringArray.push(token);
		}
		if (stringArray.length > 2) {
			return [stringArray[stringArray.length - 1]];
		}
		return stringArray;
	}

	async handleKeywords(parseResult: AutocompleteParseResult): Promise<[]> {
		const suggestKeywords = parseResult.suggestKeywords;
		if (!suggestKeywords) {
			return [];
		}
		return suggestKeywords.map((keyword) => {
			let value = parseResult.lowerCase
				? keyword.value.toLowerCase()
				: keyword.value;
			return {
				label: value,
				insertText: value,
				documentation: "documentation",
				detail: "<关键字>",
				kind: this.keywordKind,
				sortText: this.SORT_TEXT.Keyword + keyword.weight + value,
			};
		});
	}

	// async handleColRefKeywords(parseResult,
	// 	colRefPromise: Promise<>
	// ): Promise<[]> {
	// 	const suggestColRefKeywords = parseResult.suggestColRefKeywords;
	// 	if (!suggestColRefKeywords) {
	// 		return [];
	// 	}
	// 	// Wait for the column reference type to be resolved to pick the right keywords
	// 	const colRef = await colRefPromise;
	// 	const colRefKeywordSuggestions = [];
	// 	Object.keys(suggestColRefKeywords).forEach((typeForKeywords) => {
	// 		if (
	// 			matchesType(
	// 				'',
	// 				[typeForKeywords],
	// 				[colRef.type.toUpperCase()]
	// 			)
	// 		) {
	// 			suggestColRefKeywords[typeForKeywords].forEach((keyword) => {
	// 				colRefKeywordSuggestions.push({
	// 					value: this.parseResult.lowerCase
	// 						? keyword.toLowerCase()
	// 						: keyword,
	// 					meta: MetaLabels.Keyword,
	// 					category: Category.ColRefKeyword,
	// 					popular: false,
	// 					details: {
	// 						type: colRef.type,
	// 					},
	// 				});
	// 			});
	// 		}
	// 	});
	// 	return colRefKeywordSuggestions;
	// }

	async handleDatabases(parseResult: AutocompleteParseResult): Promise<[]> {
		const suggestDatabases = parseResult.suggestDatabases;
		if (!suggestDatabases) {
			return [];
		}
		const databaseSuggestions = [];
		try {
			let prefix = suggestDatabases.prependQuestionMark ? "? " : "";
			if (suggestDatabases.prependFrom) {
				prefix += parseResult.lowerCase ? "from " : "FROM ";
			}
			for (const dbEntry of this.dbSchema) {
				const name = dbEntry.dbName;
				if (name !== "") {
					databaseSuggestions.push({
						label: name,
						insertText: prefix + this.backTickIfNeeded(name),
						documentation: "documentation",
						detail: `<数据库>`,
						kind: this.databaseKind,
						sortText: this.SORT_TEXT.Database + +name,
					});
				}
			}
		} catch (err) {
			console.log(err);
		}

		return databaseSuggestions;
	}

	async handleTables(parseResult: AutocompleteParseResult): Promise<[]> {
		const suggestTables = parseResult.suggestTables;
		if (!suggestTables) {
			return [];
		}

		const getTableSuggestions = async (): Promise<[]> => {
			let prefix = suggestTables.prependQuestionMark ? "? " : "";
			if (suggestTables.prependFrom) {
				prefix += parseResult.lowerCase ? "from " : "FROM ";
			}

			const database =
				suggestTables.identifierChain &&
				suggestTables.identifierChain.length === 1
					? suggestTables.identifierChain[0].name
					: this.selectedCatalog;

			let tableSuggestions: [] = [];

			try {
				return this.getTableSuggestByDbName(database);
			} catch (err) {}

			return tableSuggestions;
		};

		return await getTableSuggestions();
	}

	async handleColumns(parseResult: AutocompleteParseResult): Promise<[]> {
		const suggestColumns = parseResult.suggestColumns;
		if (!suggestColumns) {
			return [];
		}
		let columnSuggestions: [] = [];
		for (const table of suggestColumns.tables) {
			const database =
				table.identifierChain && table.identifierChain.length === 2
					? table.identifierChain[0].name
					: this.selectedCatalog;
			const tableName =
				table.identifierChain && table.identifierChain.length === 1
					? table.identifierChain[0].name
					: table.identifierChain[1].name;
			const result = await this.getTableColumn(database, tableName);
			columnSuggestions = columnSuggestions.concat(result);
		}

		return columnSuggestions;
	}

	public async getTableColumn(database: String, tableName: String) {
		const columnSuggestions: [] = [];
		columnSuggestions.push(
			...this.getTableColumnSuggestByTable(database, tableName)
		);
		if (columnSuggestions.length == 0) {
			const fileds = await this.onInputTableColumn(database, tableName);

			if (fileds && fileds.length > 0) {
				const currentDb = this.dbSchema.find(
					(db) => db.dbName === database
				);
				const currentTable = currentDb.tables.find(
					(item) => item.tblName === tableName
				);
				currentTable.tableColumns = fileds;
			}

			fileds.forEach((field) => {
				columnSuggestions.push({
					label: field.columnName ? field.columnName : "",
					kind: this.fieldKind,
					detail: `${database}.${tableName}`,
					sortText: `${this.SORT_TEXT.Column}${field.columnName}`,
					insertText: this.backTickIfNeeded(
						field.columnName ? field.columnName : ""
					),
				});
			});
		}
		return columnSuggestions;
	}

	public backTickIfNeeded(identifier: string) {
		const quoteChar = "`";
		const operators = [
			"=",
			"<>",
			"<",
			"<=",
			">",
			">=",
			"+",
			"-",
			"*",
			"/",
			"%",
			"(",
			")",
			",",
			";",
		];
		if (identifier.indexOf(quoteChar) === 0) {
			return identifier;
		}
		if (
			this.dbKeywords.some(
				(key) => key.toUpperCase() === identifier.toUpperCase()
			) ||
			operators.some((o) => identifier.indexOf(o) != -1)
		) {
			return quoteChar + identifier + quoteChar;
		}

		if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(identifier)) {
			return quoteChar + identifier + quoteChar;
		}
		return identifier;
	}

	/**
	 * 获取自定义联想建议
	 */
	getCustomSuggest(startsWith$) {
		return this.customKeywords.map((keyword) => ({
			label: keyword,
			kind: this.monaco.languages.CompletionItemKind.Keyword,
			detail: "",
			sortText: `${this.SORT_TEXT.Keyword}${keyword}`,
			// Fix插入两个$符号
			insertText: startsWith$ ? keyword.slice(1) : keyword,
		}));
	}

	/**
	 * 获取所有字段
	 */
	getAllTableColumn() {
		const tableColumns = [];
		this.dbSchema.forEach((db) => {
			db.tables.forEach((table) => {
				table.tableColumns.forEach((field) => {
					tableColumns.push({
						label: field.columnName ? field.columnName : "",
						kind: this.fieldKind,
						detail: `<字段>`,
						sortText: `${this.SORT_TEXT.Column}${field.columnName}`,
						insertText: this.backTickIfNeeded(
							field.columnName ? field.columnName : ""
						),
					});
				});
			});
		});
		return tableColumns;
	}

	/**
	 * 获取数据库库名联想建议
	 */
	getDataBaseSuggest() {
		return this.dbSchema.map((db) => {
			return {
				label: db.dbName ? db.dbName : "",
				kind: this.databaseKind,
				detail: `<数据库>`,
				sortText: `${this.SORT_TEXT.Database}${db.dbName}`,
				insertText: this.backTickIfNeeded(db.dbName ? db.dbName : ""),
			};
		});
	}

	/**
	 * 获取关键字联想建议
	 * @param {*} keyword
	 */
	getKeywordSuggest() {
		return this.dbKeywords.map((keyword) => ({
			label: keyword,
			kind: this.keywordKind,
			detail: "<关键字>",
			sortText: `${this.SORT_TEXT.Keyword}${keyword}`,
			// Fix插入两个$符号
			insertText: keyword.startsWith("$") ? keyword.slice(1) : keyword,
		}));
	}

	/**
	 * 获取数据库表名建议
	 */
	getTableSuggest() {
		const tables = [];
		this.dbSchema.forEach((db) => {
			db.tables.forEach((table) => {
				tables.push({
					label: table.tblName ? table.tblName : "",
					kind: this.tableKind,
					detail: `<表> ${db.dbName} ${
						table.tblComment ? table.tblComment : ""
					}`,
					sortText: `${this.SORT_TEXT.Table}${table.tblName}`,
					insertText: this.backTickIfNeeded(
						table.tblName ? table.tblName : ""
					),
					documentation: table.tblComment ? table.tblComment : "",
				});
			});
		});
		return tables;
	}

	getTableSuggestByDbName(dbName) {
		if (!dbName) {
			return [];
		}
		const currentDb = this.dbSchema.find((db) => db.dbName === dbName);
		const tables = [];
		if (currentDb && currentDb.tables && currentDb.tables.length > 0) {
			currentDb.tables.forEach((table) => {
				tables.push({
					label: table.tblName ? table.tblName : "",
					kind: this.tableKind,
					detail: `${currentDb.dbName}`,
					sortText: `${this.SORT_TEXT.Table}${table.tblName}`,
					insertText: this.backTickIfNeeded(
						table.tblName ? table.tblName : ""
					),
					documentation: table.tblComment ? table.tblComment : "",
					tableColumns: table.tableColumns,
				});
			});
		}
		return tables;
	}

	/**
	 * 根据表名获取所有表字段
	 * @param {*} table
	 * @param {*} column
	 */
	getTableColumnSuggestByTable(dbName, tableName) {
		const defaultFields = [];
		const tables = this.getTableSuggestByDbName(dbName);
		tables
			.filter((item) => item.label === tableName)
			.forEach((table) => {
				table.tableColumns &&
					table.tableColumns.forEach((field) => {
						defaultFields.push({
							label: field.columnName ? field.columnName : "",
							kind: this.fieldKind,
							detail: `${dbName}.${tableName}`,
							sortText: `${this.SORT_TEXT.Column}${field.columnName}`,
							insertText: this.backTickIfNeeded(
								field.columnName ? field.columnName : ""
							),
							documentation: {
								value: `
  ### 数据库: ${field.dbName}
  ### 表: ${field.tblName}
  ### 注释: ${field.commentName ? field.commentName : ""}
              `,
							},
						});
					});
			});
		const asyncFields = [];
		return [...defaultFields, ...asyncFields];
	}
}

function returnCompletionItemsByVersion(
	value: ICompletionItem[],
	monacoVersion: IMonacoVersion
) {
	switch (monacoVersion) {
		case "0.13.2":
			return value;
		case "0.15.6":
			return {
				suggestions: value,
			};
		default:
			throw Error("Not supported version");
	}
}
